package com.apache.poi.word.controller;

import com.apache.poi.word.config.policy.BreakPageNoneRenderPolicy;
import com.apache.poi.word.domain.vo.word.*;
import com.apache.poi.word.utils.WordUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.Includes;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: HUANG GY.
 * @Date: 2022/2/9 14:28
 * @Description: com.apache.poi.word.controller
 */
@RestController
@RequestMapping("/work1")
@Api(value = "文档合并")
public class Work1Controller {

    @GetMapping("/mergeDoc")
    @ApiOperation(value = "mergeDoc", notes = "mergeDoc")
    public static Object mergeDoc() throws Exception {
        String file01_path = "docs/work1/file01.docx";
        String file02_path = "docs/work1/file02.docx";
        String file03_path = "docs/work1/file03.docx";
        List<String> pathList = Stream.of(file01_path, file02_path, file03_path).collect(Collectors.toList());
        List<NiceXWPFDocument> documentList = new ArrayList<>();
        //封面
        NiceXWPFDocument coverDoc = getDocCover();
        //页眉页脚
        headFoot(coverDoc);
        documentList.add(coverDoc);

        //目录
        String mulu = "docs/work1/mulumulu.docx";
        NiceXWPFDocument muluDoc = WordUtil.in2niceDocPage(mulu);
        documentList.add(muluDoc);
//        NiceXWPFDocument catalogueDoc = catalogue();
//        documentList.add(catalogueDoc);


        for (int i = 0; i < pathList.size(); i++) {
            String pathName = pathList.get(i);
            NiceXWPFDocument doc = null ;
            if (i != i-1) {
                doc = WordUtil.in2niceDocPage(pathName);
            }else{
                doc = WordUtil.in2niceDoc(pathName);
            }
            documentList.add(doc);
        }
        //各个代表队名单
        NiceXWPFDocument teamListDoc = teamList();
        documentList.add(teamListDoc);

        int size = documentList.size();
        if (size == 0){
            throw new IllegalArgumentException("没有需要合并的文档");
        }
        NiceXWPFDocument mainDoc = documentList.get(0);
        if (size > 1){
            for (int i = 1; i < size; i++) {
                NiceXWPFDocument subDoc = documentList.get(i);
                 mainDoc = mainDoc.merge(subDoc);            }
        }
        mainDoc.enforceUpdateFields();
        // 生成新文档
        FileOutputStream out = new FileOutputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/create_table001.docx");
        mainDoc .write(out);
        mainDoc .close();
        out.close();
        return "啊哈哈test001";
    }

    /**
     *  增加一个封面页
     * @return
     */
    public static NiceXWPFDocument getDocCover() throws Exception {
        //封面文件流
        InputStream coverPicInputStream01 = new FileInputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/aa.png");
        InputStream coverPicInputStream02 = new FileInputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/aa.png");
        List<InputStream> picInputstreamList = new ArrayList<>();
        picInputstreamList.add(coverPicInputStream01);
        picInputstreamList.add(coverPicInputStream02);
        NiceXWPFDocument doc = WordUtil.coverPage(picInputstreamList);
        return doc;
    }


    /**
     *  页眉页脚
     * @param doc
     */
    private static void headFoot(NiceXWPFDocument doc) throws IOException, InvalidFormatException {
        String [] imgFileArr = {"/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/aa.png","/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/aa.png","/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/aa.png"};
        List<FileInputStream> logoInputStreamList = Arrays.asList(imgFileArr).stream().map(e -> {
            FileInputStream inputStream = null;
            try {
                inputStream = new FileInputStream(e);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            }
            return inputStream;
        }).collect(Collectors.toList());

        CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy( doc, sectPr );
        XWPFHeader header = headerFooterPolicy.createHeader( XWPFHeaderFooterPolicy.DEFAULT );
        XWPFParagraph paragraph = header.createParagraph();
        XWPFRun run = paragraph.createRun();
        int size = logoInputStreamList.size();
        XWPFPicture [] pictureArr = new XWPFPicture[size];
//        for (int i = 0; i < size; i++) {
//            FileInputStream logoInputStream = logoInputStreamList.get(i);
//            pictureArr[i] = run.addPicture( logoInputStream, XWPFDocument.PICTURE_TYPE_JPEG, imgFileArr[i], Units.toEMU( 150 ), Units.toEMU( 50 ) );
//            List<XWPFPictureData> allPackagePictures = header.getAllPackagePictures();
//            List<XWPFPictureData> allPackagePictureList = new ArrayList(allPackagePictures);
//            allPackagePictureList.sort((o1,o2)->{
//                return o1.getFileName().compareTo(o2.getFileName());
//            });
//            for (XWPFPictureData picturedata : allPackagePictureList) {
//                String blipID = header.getRelationId( picturedata );
//                pictureArr[i].getCTPicture().getBlipFill().getBlip().setEmbed( blipID );
//            }
//        }
//        for (int i = 0; i < logoInputStreamList.size(); i++) {
//            WordUtil.picAttribute(run, i,150,40,151*i,0);
//        }
        XWPFRun runText = paragraph.createRun();
        runText.setText("            546532134515341                        乒乓球   2022年10月01日");

        //页脚
        XWPFFooter footer =  headerFooterPolicy.createFooter(STHdrFtr.DEFAULT);
        XWPFParagraph paragraphFoot = footer.createParagraph();
        paragraphFoot.setAlignment(ParagraphAlignment.RIGHT);
        /*
         * 生成页码
         * 页码右对齐
         * */
        run = paragraphFoot.createRun();
        run.setText("第");
        WordUtil.setXWPFRunStyle(run,"仿宋",10);

        run = paragraphFoot.createRun();
        CTFldChar fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraphFoot.createRun();
        CTText ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE  /* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        WordUtil.setXWPFRunStyle(run,"仿宋",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));

        run = paragraphFoot.createRun();
        run.setText("页 总共");
        WordUtil.setXWPFRunStyle(run,"仿宋",10);

        run = paragraphFoot.createRun();
        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraphFoot.createRun();
        ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("NUMPAGES  /* MERGEFORMAT ");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        WordUtil.setXWPFRunStyle(run,"仿宋",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));

        run = paragraphFoot.createRun();
        run.setText("页");
        WordUtil.setXWPFRunStyle(run,"仿宋",10);
    }


    /**
     *  各代表队名单
     * @return
     * @throws Exception
     */
    public static NiceXWPFDocument teamList() throws  Exception {

        List<OrganisationPeopleVO> dataList = new ArrayList<>();
        OrganisationPeopleVO organisationPeopleVO = new OrganisationPeopleVO();
        organisationPeopleVO.setOrganizationName("福建省");
        organisationPeopleVO.setLeaderName("张三丰");
        organisationPeopleVO.setCoachName("教练,教练,教练,教练,教练");
        List<GroupAthleteVO> groupAthleteList = new ArrayList<>();
        GroupAthleteVO groupAthleteVO = new GroupAthleteVO();
        groupAthleteVO.setGroupName("男子组");

        List<AthleteNameBirthdayVO> athleteList = new ArrayList<>();
        groupAthleteVO.setAthleteList(athleteList);
        AthleteNameBirthdayVO athleteNameBirthdayVO =  new AthleteNameBirthdayVO();
        AthleteNameBirthdayVO athleteNameBirthdayV1 =  new AthleteNameBirthdayVO();
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayV1);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteList.add(athleteNameBirthdayVO);
        athleteNameBirthdayVO.setAthleteName("张三");
        athleteNameBirthdayVO.setBirthday("2003.05.23");
        athleteNameBirthdayV1.setAthleteName("你我他");
        athleteNameBirthdayV1.setBirthday("2007.11.03");

        groupAthleteList.add(groupAthleteVO);
        groupAthleteList.add(groupAthleteVO);
        groupAthleteList.add(groupAthleteVO);

        organisationPeopleVO.setGroupAthleteList(groupAthleteList);
        dataList.add(organisationPeopleVO);
        dataList.add(organisationPeopleVO);
        dataList.add(organisationPeopleVO);

        Map<String,Object> params = new HashMap<>();

        params.put("nested", Includes.ofStream(WordUtil.getFileInputStream("docs/work1/各代表队名单INNER.docx")).setRenderModel(dataList).create());
        InputStream fileInputStream = WordUtil.getFileInputStream("docs/work1/各代表队名单OUT.docx");

        ConfigureBuilder builder = Configure.builder();
        builder.bind("breakPageFlag", new BreakPageNoneRenderPolicy());

        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,builder.build()).render(params);
//        template.writeAndClose(new FileOutputStream("D:/05_code/gitee/word-demo/src/main/resources/docs/work1/各代表队名单OUT001.docx"));
        WordUtil.close(fileInputStream);
        NiceXWPFDocument xwpfDocument = template.getXWPFDocument();
        return xwpfDocument;
    }

    /**
     *  目录
     * @return
     * @throws Exception
     */
    public static NiceXWPFDocument catalogue() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        List<CatalogueVO> datas = new ArrayList<>();
        datas.add(new CatalogueVO("1.广西壮族自治区第十四届运动会竞技体育项目竞赛规程总则"));
        datas.add(new CatalogueVO("2.仲裁委员会条例"));
        datas.add(new CatalogueVO("3.大会活动日程表"));
        datas.add(new CatalogueVO("4.各代表队名单"));
        InputStream fileInputStream = WordUtil.getFileInputStream("docs/work1/目录.docx");
        params.put("catalogue",datas);
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        NiceXWPFDocument xwpfDocument = template.getXWPFDocument();
//        template.writeAndClose(new FileOutputStream("D:/05_code/gitee/word-demo/src/main/resources/docs/work1/目录001.docx"));
        xwpfDocument.createParagraph().setPageBreak(Boolean.TRUE);
        WordUtil.close(fileInputStream);
        return xwpfDocument;
    }


    public static void main(String[] args) throws Exception {
        mergeDoc();
//        subDoc001();
//        catalogue();
    }

}
